A debugging tool is one type of computing tool, typically used to trace the execution of executable code for finding programming errors, or bugs. In order for a debugging tool to be useful, the developer using the tool needs to have access to the source code that was used to compile the executable code being debugged, along with the symbol data generated by the compilation process. Among other reasons, this is because when tracing a program's execution, a developer does not want to see the numerical address associated with a memory location, but instead wants to see the name (label) or the like assigned to that memory address in the source code. To this end, debugging tools merge files containing the source code and symbol data with the executable code being debugged, to present the code to the user with meaningful information. In this way, the developer can immediately relate the given name to a program step being executed, e.g., to recognize things such as what named routine is being called, what named variable is being written or read, and so on.
However, locating the correct symbol information for debugging or other purposes is a complicated problem. For example, when tracing a program's execution takes the developer into operating system code, the symbols for that operating system code are different for each revision, according to release or build number. As a result, in order to find the correct symbols for the particular operating system code being debugged, the developer must know or be able to find out the correct version releases of the operating system. The developer must also know or be able to determine the respective locations (path) for each set of symbol files.
Thus, to debug applications run on contemporary operating systems, a developer (or development team) needs to perform a substantial amount of setup work, which adversely impacts the debugging process. For example, application developers running applications on contemporary operating system code need to copy gigabytes of operating system source code, install thousands of symbol and source files onto the machine that is being used for debugging (or onto some local network share connected to that machine), setup their own operating system build environment, manage different versions of the platform, and perform many other administrative tasks necessary in a large software development project. As can be readily appreciated, not only does such setup complexity consume huge amounts of storage, (on the order of tens of gigabytes when the copied files are expanded and the environment built), but is extremely costly in terms of time.
Further, even after the developers set up their own build environment, they are still not able to fully utilize the source code. They must build (compile) the operating system in order to have the necessary operating system symbols for debugging their application, and this build may not match the retail product. Finally, after all this preparation, in many instances most of the installed symbol and source files are never actually needed.
In sum, there are numerous difficulties and drawbacks in working with a large amount of symbol files and/or source code files, yet in many cases, such as with contemporary operating systems, the many versions and platforms available need to be supported. Note that other symbol-based computing tools, such as performance monitoring tools, fault-injection tools, diagnostic tools and so on have similar problems.